#!/usr/bin/env python3
"""
Enhanced Multi-Website Browser Launcher.

This module provides enhanced browser launching capabilities for multiple websites,
integrating with the new session management and website profile system.
"""

import os
import sys
import argparse
import time
import logging
from typing import Dict, List, Optional, Any

from models import WebsiteProfile
from session_manager import SessionManager
from website_manager import WebsiteManager
from browser_manager import BrowserManager


class MultiWebsiteBrowserLauncher:
    """Enhanced browser launcher with multi-website support."""
    
    def __init__(self):
        """Initialize the multi-website browser launcher."""
        self.session_manager = SessionManager()
        self.website_manager = WebsiteManager()
        self.browser_manager = BrowserManager()
        
        self.logger = self._setup_logging()
    
    def _setup_logging(self) -> logging.Logger:
        """Setup logging configuration."""
        logger = logging.getLogger("MultiWebsiteLauncher")
        logger.setLevel(logging.INFO)
        
        if not logger.handlers:
            handler = logging.StreamHandler()
            formatter = logging.Formatter(
                '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
            )
            handler.setFormatter(formatter)
            logger.addHandler(handler)
        
        return logger
    
    def launch_single_website(self, username: str, website_id: str, 
                             count: int = 1, isolated: bool = False) -> bool:
        """
        Launch browsers for a single website.
        
        Args:
            username: User identifier
            website_id: Website profile identifier
            count: Number of browser instances to launch
            isolated: Whether to create isolated instances
            
        Returns:
            True if successful, False otherwise
        """
        try:
            # Get website profile
            profile = self.website_manager.get_profile(website_id)
            if not profile:
                self.logger.error(f"Website profile not found: {website_id}")
                print(f"❌ Website profile not found: {website_id}")
                self._show_available_profiles()
                return False
            
            # Get user session
            session = self.session_manager.get_session(username, website_id)
            if not session:
                self.logger.warning(f"No active session found for {username} @ {website_id}")
                print(f"⚠️  No active session found for {username} @ {website_id}")
                print("💡 Please run login first: python login.py --website {website_id} -u {username}")
                
                # Try to download from cloud
                from auth_manager import AuthenticationManager
                auth_manager = AuthenticationManager()
                auth_state = auth_manager.download_session_state(username, website_id)
                
                if auth_state:
                    print("📥 Found session in cloud storage, creating local session...")
                    session = self.session_manager.create_session(
                        website_id=website_id,
                        username=username,
                        auth_state=auth_state
                    )
                    if not session:
                        print("❌ Failed to create session from cloud data")
                        return False
                else:
                    print("❌ No session found in cloud storage either")
                    return False
            
            print(f"🚀 Launching {count} browser instance(s) for {profile.display_name}")
            print(f"👤 User: {username}")
            print(f"🌐 Website: {profile.target_url}")
            print(f"🔗 Session: {session.session_id}")
            print()
            
            # Launch browsers
            instances = self.browser_manager.launch_browser(
                profile=profile,
                session=session,
                isolated=isolated,
                count=count
            )
            
            if instances:
                print(f"✅ Successfully launched {len(instances)} browser instance(s)")
                
                for i, instance in enumerate(instances, 1):
                    print(f"   Browser {i}: PID {instance.process_id}")
                
                print()
                print("📋 Browser Information:")
                print(f"   Profile Directory: {instances[0].profile_dir}")
                print(f"   Target URL: {instances[0].target_url}")
                print(f"   Isolation: {'Yes' if isolated else 'No (Shared)'}")
                
                print()
                print("💡 Tips:")
                print("   - These browsers will continue running after this script exits")
                print("   - Login state and extensions are shared across instances")
                print("   - You can safely close this terminal window")
                
                return True
            else:
                print("❌ Failed to launch any browser instances")
                return False
                
        except Exception as e:
            self.logger.error(f"Failed to launch single website: {e}")
            print(f"❌ Error launching browsers: {e}")
            return False
    
    def launch_multiple_websites(self, username: str, website_ids: List[str], 
                                count_per_website: int = 1, isolated: bool = False) -> bool:
        """
        Launch browsers for multiple websites.
        
        Args:
            username: User identifier
            website_ids: List of website profile identifiers
            count_per_website: Number of browser instances per website
            isolated: Whether to create isolated instances
            
        Returns:
            True if any websites launched successfully, False otherwise
        """
        try:
            print(f"🚀 Multi-Website Browser Launch")
            print(f"👤 User: {username}")
            print(f"🌐 Websites: {', '.join(website_ids)}")
            print(f"🔢 Instances per website: {count_per_website}")
            print(f"🔒 Isolation: {'Yes' if isolated else 'No (Shared)'}")
            print()
            
            # Get website profiles
            profiles = {}
            for website_id in website_ids:
                profile = self.website_manager.get_profile(website_id)
                if profile:
                    profiles[website_id] = profile
                else:
                    print(f"⚠️  Skipping unknown website: {website_id}")
            
            if not profiles:
                print("❌ No valid website profiles found")
                self._show_available_profiles()
                return False
            
            # Get user sessions
            sessions = []
            for website_id in profiles.keys():
                session = self.session_manager.get_session(username, website_id)
                if session:
                    sessions.append(session)
                else:
                    print(f"⚠️  No session found for {website_id}, attempting cloud download...")
                    
                    # Try cloud download
                    from auth_manager import AuthenticationManager
                    auth_manager = AuthenticationManager()
                    auth_state = auth_manager.download_session_state(username, website_id)
                    
                    if auth_state:
                        session = self.session_manager.create_session(
                            website_id=website_id,
                            username=username,
                            auth_state=auth_state
                        )
                        if session:
                            sessions.append(session)
                            print(f"✅ Created session for {website_id} from cloud")
                        else:
                            print(f"❌ Failed to create session for {website_id}")
                    else:
                        print(f"❌ No cloud session found for {website_id}")
            
            if not sessions:
                print("❌ No valid sessions found")
                print("💡 Please run login for each website first")
                return False
            
            # Launch browsers for all websites
            launched_browsers = self.browser_manager.launch_multi_website_browsers(
                sessions=sessions,
                profiles=profiles,
                count_per_website=count_per_website,
                isolated=isolated
            )
            
            if launched_browsers:
                total_instances = sum(len(instances) for instances in launched_browsers.values())
                print(f"✅ Successfully launched {total_instances} browser instances across {len(launched_browsers)} websites")
                print()
                
                for website_id, instances in launched_browsers.items():
                    profile = profiles[website_id]
                    print(f"🌐 {profile.display_name}:")
                    for i, instance in enumerate(instances, 1):
                        print(f"   Browser {i}: PID {instance.process_id}")
                    print()
                
                print("💡 All browsers are now running independently")
                return True
            else:
                print("❌ Failed to launch any browsers")
                return False
                
        except Exception as e:
            self.logger.error(f"Failed to launch multiple websites: {e}")
            print(f"❌ Error launching browsers: {e}")
            return False
    
    def launch_all_user_sessions(self, username: str, count_per_website: int = 1, 
                                isolated: bool = False) -> bool:
        """
        Launch browsers for all available user sessions.
        
        Args:
            username: User identifier
            count_per_website: Number of browser instances per website
            isolated: Whether to create isolated instances
            
        Returns:
            True if any sessions launched successfully, False otherwise
        """
        try:
            # Get all user sessions
            sessions = self.session_manager.get_user_sessions(username)
            
            if not sessions:
                print(f"❌ No active sessions found for user: {username}")
                print("💡 Please run login for websites first")
                return False
            
            print(f"🚀 Launching browsers for all sessions of user: {username}")
            print(f"📋 Found {len(sessions)} active session(s)")
            print()
            
            website_ids = [session.website_id for session in sessions]
            return self.launch_multiple_websites(
                username=username,
                website_ids=website_ids,
                count_per_website=count_per_website,
                isolated=isolated
            )
            
        except Exception as e:
            self.logger.error(f"Failed to launch all user sessions: {e}")
            print(f"❌ Error launching browsers: {e}")
            return False
    
    def _show_available_profiles(self):
        """Show available website profiles."""
        try:
            profiles = self.website_manager.list_profiles(include_templates=True)
            
            if profiles:
                print("📋 Available website profiles:")
                for profile in profiles:
                    template_marker = ""
                    if profile.website_id in self.website_manager.list_templates():
                        template_marker = " (Template)"
                    
                    print(f"   - {profile.website_id}: {profile.display_name}{template_marker}")
                print()
                print("💡 To add a new profile: python manage.py add-website --help")
            else:
                print("📝 No website profiles available")
                print("💡 Add profiles using: python manage.py add-website --help")
            
        except Exception as e:
            self.logger.error(f"Failed to show available profiles: {e}")
    
    def show_sessions_summary(self, username: Optional[str] = None):
        """Show summary of available sessions."""
        try:
            if username:
                sessions = self.session_manager.get_user_sessions(username)
                print(f"📋 Active sessions for {username}:")
            else:
                sessions = list(self.session_manager._active_sessions.values())
                print("📋 All active sessions:")
            
            if not sessions:
                print("   No active sessions found")
                return
            
            for session in sessions:
                status_icon = "✅" if session.is_valid() else "❌"
                expiry_str = ""
                if session.expires_at:
                    expiry_str = f" (expires {session.expires_at.strftime('%Y-%m-%d %H:%M')})"
                
                profile = self.website_manager.get_profile(session.website_id)
                website_name = profile.display_name if profile else session.website_id
                
                print(f"   {status_icon} {session.username} @ {website_name}{expiry_str}")
            
        except Exception as e:
            self.logger.error(f"Failed to show sessions summary: {e}")


def create_argument_parser() -> argparse.ArgumentParser:
    """Create the command line argument parser."""
    parser = argparse.ArgumentParser(
        description='Multi-Website Browser Launcher - Enhanced Version',
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog='''
Usage Examples:
  # Launch single website
  python multi_open.py -u 13800138000 --website geekbi
  python multi_open.py -u user --website tabcut -c 3
  
  # Launch multiple websites
  python multi_open.py -u 13800138000 --websites geekbi,tabcut,menglar
  python multi_open.py -u user --websites geekbi,tabcut -c 2 --isolated
  
  # Launch all user sessions
  python multi_open.py -u 13800138000 --all-sessions
  
  # Show available profiles and sessions
  python multi_open.py --list-profiles
  python multi_open.py --show-sessions -u 13800138000
        '''
    )
    
    # User identification
    parser.add_argument('-u', '--username', 
                       help='Username (required for launching browsers)')
    
    # Website selection
    website_group = parser.add_mutually_exclusive_group()
    website_group.add_argument('--website', '--site', dest='website_id',
                              help='Single website profile ID')
    website_group.add_argument('--websites', '--sites', dest='website_ids',
                              help='Comma-separated list of website profile IDs')
    website_group.add_argument('--all-sessions', action='store_true',
                              help='Launch browsers for all user sessions')
    
    # Browser configuration
    parser.add_argument('-c', '--count', type=int, default=1,
                       help='Number of browser instances per website (default: 1)')
    parser.add_argument('--isolated', action='store_true',
                       help='Create isolated browser instances (default: shared)')
    
    # Information commands
    info_group = parser.add_mutually_exclusive_group()
    info_group.add_argument('--list-profiles', action='store_true',
                           help='List available website profiles')
    info_group.add_argument('--show-sessions', action='store_true',
                           help='Show active sessions')
    
    # Legacy compatibility (from original open.py)
    parser.add_argument('--url', '--target-url', dest='target_url',
                       help='Target URL (legacy mode)')
    
    return parser


def main():
    """Main entry point for the enhanced browser launcher."""
    parser = create_argument_parser()
    args = parser.parse_args()
    
    launcher = MultiWebsiteBrowserLauncher()
    
    try:
        print("=" * 60)
        print("Multi-Website Browser Launcher")
        print("=" * 60)
        
        # Handle information commands
        if args.list_profiles:
            profiles = launcher.website_manager.list_profiles(include_templates=True)
            
            if not profiles:
                print("📝 No website profiles available")
                print("💡 Add profiles using: python manage.py add-website --help")
            else:
                print(f"📋 Available Website Profiles ({len(profiles)}):")
                print()
                
                for i, profile in enumerate(profiles, 1):
                    template_marker = ""
                    if profile.website_id in launcher.website_manager.list_templates():
                        template_marker = " (Built-in Template)"
                    
                    print(f"{i}. {profile.display_name}{template_marker}")
                    print(f"   ID: {profile.website_id}")
                    print(f"   URL: {profile.target_url}")
                    print(f"   Auth: {profile.auth_method.value}")
                    print()
                
                print("💡 Usage: python multi_open.py -u <username> --website <ID>")
            
            return
        
        if args.show_sessions:
            launcher.show_sessions_summary(args.username)
            return
        
        # Validate username for browser launching
        if not args.username:
            # Try to get from config for backward compatibility
            try:
                from config import USERNAME
                username = USERNAME
            except ImportError:
                username = None
            
            if not username:
                print("❌ Error: Username required")
                print("Use -u parameter or configure USERNAME in config.py")
                parser.print_help()
                return
        else:
            username = args.username
        
        # Validate browser count
        if args.count <= 0:
            print("❌ Error: Browser count must be greater than 0")
            return
        
        # Launch browsers based on selection
        success = False
        
        if args.website_id:
            # Single website mode
            success = launcher.launch_single_website(
                username=username,
                website_id=args.website_id,
                count=args.count,
                isolated=args.isolated
            )
        
        elif args.website_ids:
            # Multiple websites mode
            website_ids = [w.strip() for w in args.website_ids.split(',') if w.strip()]
            if not website_ids:
                print("❌ Error: No valid website IDs provided")
                return
            
            success = launcher.launch_multiple_websites(
                username=username,
                website_ids=website_ids,
                count_per_website=args.count,
                isolated=args.isolated
            )
        
        elif args.all_sessions:
            # All user sessions mode
            success = launcher.launch_all_user_sessions(
                username=username,
                count_per_website=args.count,
                isolated=args.isolated
            )
        
        elif args.target_url:
            # Legacy mode for backward compatibility
            print("🔄 Legacy mode detected")
            print("💡 Consider using --website for better session management")
            print()
            
            # Try to import and use the original function
            try:
                from open import open_browser_independent
                success = open_browser_independent(
                    username=username,
                    count=args.count,
                    target_url=args.target_url
                )
            except ImportError:
                print("❌ Legacy mode not available")
                success = False
        
        else:
            # No specific website selected, show help
            print("⚠️  No website specified")
            launcher.show_sessions_summary(username)
            print()
            print("💡 Options:")
            print("   --website <ID>        Launch single website")
            print("   --websites <ID1,ID2>  Launch multiple websites")
            print("   --all-sessions        Launch all user sessions")
            print("   --list-profiles       Show available profiles")
            return
        
        if success:
            print()
            print("🎉 Browser launch completed successfully!")
            print("💡 Browsers are running independently")
            
            # Show timing information
            print()
            print("⏱️  Auto-exit in 5 seconds...")
            for i in range(5, 0, -1):
                print(f"   {i}...")
                time.sleep(1)
            
            print()
            print("✅ Script completed. Browsers continue running.")
        else:
            print()
            print("❌ Browser launch failed")
            print("💡 Check the error messages above for details")
    
    except KeyboardInterrupt:
        print("\n🚫 Operation cancelled by user")
    except Exception as e:
        print(f"\n💥 Unexpected error: {e}")
        import traceback
        traceback.print_exc()
    finally:
        input("\nPress Enter to exit...")


if __name__ == "__main__":
    main()